package aufgabe3_chat;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Server_Thread extends Thread {

	
	// Die Verbindung
	private Socket connection = null;

	// InputStream
	private final int MAXZEICHEN = 257;

	// Der Master
	private Server_Administration_Control control;

	// User Name Lsit
	private Chat_User_Administration user_list;

	// User Name
	private String userName;

	// Der Logger
	private Logger logger;

	private boolean server_run;

	public Server_Thread(Socket connection,
		Server_Administration_Control control,
		Chat_User_Administration user_list, Logger logger) {

		this.user_list = user_list;
		this.connection = connection;
		this.control = control;
		server_run = true;
		setDaemon(false);
		this.logger = logger;
		logger.log("Server Thread", "Server Thread", "Erzeugt");
	}

	@Override
	public void run() {
		InputStream eingang;
		PrintWriter out;

		try {
			eingang = connection.getInputStream();
			out = new PrintWriter(connection.getOutputStream(), true);
		} catch (IOException e) {
			control.server_thread_counter_down();
			logger.log("Server Thread", "Error", "FEHLER BEI CONNECTIONAUFBAU");
			return;
		}

		// Handle Connection
		byte[] zeichen = new byte[MAXZEICHEN];
		
		try {
			while (server_run) {
				// Handle Connection
				for(int pos = 0; pos < zeichen.length; pos++){
					zeichen[pos] = 0;
				}
					
					int number_zeichen = eingang.read(zeichen);
					//logger.log("Server Thread","Anzahl der Bytes(available):", "" + number_zeichen);
					
					String input = "";
					String chars = new String(zeichen);

					for (int i = 0; i < number_zeichen - 2; i++) {
						input = input + chars.charAt(i);
					}		
					// logger.log("Server Thread", "Inputlaenge","" + input.length());

					int rest = eingang.available();
					if (rest > 0) {
						eingang.skip(rest + 1);
					}
					
					String[] splitInput = input.split(" ", 2);
					//logger.log("Server Thread", "Splitinput 0", "Begin :" + splitInput[0] + ": End");
					if (splitInput.length == 2) {
						//logger.log("Server Thread","Splitinput 1","Begin :" + splitInput[1] +": End");
						if (splitInput[0].equals("NEW")) {
							if (splitInput[1].matches("[\\w]*") && splitInput[1].length() < 21 && userName == null) {
								user_list.add(connection.getInetAddress().getHostName() , splitInput[1]);
								userName = splitInput[1];
								out.println("OK");
							} else {
								out.println("ERROR not valid username or you alrady have one: " + splitInput[1]);
							}
						} else {
							out.println("ERROR Invallid command Closing" + input);
						}
					} else {
						if (splitInput[0].equals("INFO") && userName != null) {
							//logger.log("Server Thread", "INFO", "Start");
							//logger.log("Server Thread", "INFO", ""+ user_list.get_user_list_size());
							out.print("LIST "+ user_list.get_user_list_size());
							for (String key : user_list.key_set()) { 
								out.print(" " + key + " " + user_list.get_val(key));
								//logger.log("Server Thread", "INFO", " " + key + " " + user_list.get_val(key));
							}
							out.println();
							//logger.log("Server Thread", "INFO", "End");
						} else if (splitInput[0].equals("BYE")) {
							logger.log("Server Thread", "BYE", "Closing Start");
							out.println("BYE");
							user_list.remove(connection.getInetAddress().getHostName());
							server_run = false;
						} else {
							out.println("ERROR Invallid command Closing" + input);
							user_list.remove(connection.getInetAddress().getHostName());
							server_run = false;
						}
					}
				}
			

			eingang.close();
			out.close();
			connection.close();
			user_list.remove(userName);
			control.server_thread_counter_down();
			logger.log("Server Thread", "Server Thread", "Closing");
		} catch (IOException e) {
			user_list.remove(userName);
			control.server_thread_counter_down();
			logger.log("Server Thread", "ERROR", "IOException");
		}
	}
}
